package de.dhbw.karlsruhe.picsim.model.actions.impl;

import de.dhbw.karlsruhe.picsim.model.actions.*;
import de.dhbw.karlsruhe.picsim.model.memory.RegisterValue;
import de.dhbw.karlsruhe.picsim.util.Bits;
import de.dhbw.karlsruhe.picsim.util.impl.Lengths;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: goesen
 * Date: Apr 13, 2010
 * Time: 12:13:55 AM
 */
public final class ActionFactoryImpl implements ActionFactory {
    private static final Log log = LogFactory.getLog(ActionFactoryImpl.class);


    @NotNull
    @Override
    public WriteInWAction createWriteInWAction(@NotNull final RegisterValue value) {
        return new WriteInWActionImpl(value);
    }

    @NotNull
    @Override
    public WriteInFileAction createWriteInFileAction(@NotNull final Bits address,
                                                     @NotNull final RegisterValue value) {
        return new WriteInFileActionImpl(address, value);
    }

    @NotNull
    @Override
    public StatusAction setZeroBit() {
        return createStatusAction(StatusAction.AffectedStatus.ZERO, true);
    }

    @NotNull
    @Override
    public StatusAction clearZeroBit() {
        return createStatusAction(StatusAction.AffectedStatus.ZERO, false);
    }

    @NotNull
    @Override
    public StatusAction setCarryBit() {
        return createStatusAction(StatusAction.AffectedStatus.CARRY, true);
    }

    @NotNull
    @Override
    public StatusAction clearCarryBit() {
        return createStatusAction(StatusAction.AffectedStatus.CARRY, false);
    }

    @NotNull
    @Override
    public PicAction setDigitCarryBit() {
        return createStatusAction(StatusAction.AffectedStatus.DIGIT_CARRY, true);
    }

    @NotNull
    @Override
    public PushToStackAction createPushToStackAction() {
        return new PushToStackActionImpl();
    }


    @NotNull
    @Override
    public PopFromStackAction popFromStackAction() {
        return new PopFromStackActionImpl();
    }

    @NotNull
    @Override
    public ModifyProgramCounterAction createSkipNextCommandAction() {
        return new ModifyProgramCounterActionImpl();
    }

    @NotNull
    @Override
    public ModifyProgramCounterAction createElevenBitJump(@NotNull final Bits argument) {
        if (argument.getLength() != Lengths.CALL_GOTO_ARGUMENT_LENGTH) {
            log.warn("Illegal Value" + argument);
        }
        return new ModifyProgramCounterActionImpl(argument);
    }

    @NotNull
    @Override
    public List<? extends PicAction> clearWatchDog() {
        final List<PicAction> result = new ArrayList<PicAction>();
        result.add(createStatusAction(StatusAction.AffectedStatus.TIME_UP, false));
        result.add(new ClearWatchDogActionImpl());
        return result;
    }

    @NotNull
    @Override
    public PicAction clearDigitCarryBit() {
        return createStatusAction(StatusAction.AffectedStatus.DIGIT_CARRY, false);
    }

    @NotNull
    private static StatusAction createStatusAction(@NotNull final StatusAction.AffectedStatus flag,
                                                   final boolean value) {
        return new StatusActionImpl(flag, value);
    }
}
